package md.log;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import md.cm.flow.ApprovalStm;
import md.specialEqp.inspect.Procedure_Enum;
import md.system.User;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import jakarta.persistence.*;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.UUID;

/** 传递 记录；流转的操作历史明细。
 * 流转或审核的操作明细Log。 支持后退。
 * 支持多个用户 一起有权利流转。
 * 每个环节时间进度超期预警 ,给下一个节点设置时间截止期限？。
 *操作历史记录AuditOperate<(status,time,user,OPTION通过退回,MEMO,处理后转为Nextstatus,当前状态哪些Users可处理)>;
 * 普通申请单(非报告) Application申请 是否也用这个模式？？ 发起人【授权单人自己】,申请批准人=部门角色[1,2],通过END,终结状态[授权角色为空]
 *
*/

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Circulation {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private UUID id;
    /**操作时间
     * */
    @Temporal(TemporalType.DATE)
    private Date time=new Date();

    /**操作用户，
     * 不仅是正常的授权流转用户，有可能是master{有些节点需要特权主持人}操作。
     * 不会多个人一起点击流转和审批的。
     * master也有可能授权转移给另外一个人。遇到回退操作怎么变回master?回退直接要求制定新的master?从历史记录回溯User?
     * */
    @ManyToOne(fetch= FetchType.LAZY)
    @JoinColumn
    private User user;

    /**流转或审核的 结论；
     * 通过，退回, 不通过。
     * 报告想流转下一个节点都是通过。
     * 当前节点的当前User操作结果。
     * 报告书流转END终结节点的都是 通过，不会不通过，不通过应该流转回退上个节点，而不是流转终结节点。
     * 报告签字： 签名通过， 拒绝签名请回退吧；
     * 假如是投票场景应用呢：3个人只需要2个人投票赞成就能通过的，投票主持人查看签名进度赞成人数+反对人数能否按规则完成流转完结。
     */
    private Opinion_Enum opinion;

    /**理由 说明 【zeebe】一般不存储这个理由等详细；
     * 签字的： 签字User要说明 额外声明[手写名字=用户登录密码Token验证身份]
     * {签字取款双重密码/APP账户登录验证身份短信验证码App手势密码进入口令，真正支付使用密码},??高等级密码第二密码交易密码。
     * 签字 落款详细时间。
     */
    @Column(length =1024)
    private String  memo;

    /**当前状态下，还有哪些Users可处理;
     * 除了user之外的人。
     * 用来 回退，
     * 若下次 退回来后 这些用户都允许操作。
     * 签名签字投票环节的可以简化：moreUser没有意义:=null#，节点Procedure_Enum状态也不会变化。
     * 会议主持人master可能也会在moreUser中，表示也参与投票。退回投票开始环节的？
     */
    @Deprecated
    @ManyToMany
    @JoinTable(name="Circul_moreUser",joinColumns={@JoinColumn(name="circId")},inverseJoinColumns={@JoinColumn(name="userId")})
    @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL,region ="Fast")
    private List<User> moreUser;

    /**当前位于 流程 的某个节点状态。
     *【zeebe】引擎体现为UserTask的节点定义名字。名字可能变动？
     * 需要映射关系数值 代表处于某个阶段的流程节点上等待用户当中。
     */
    private Procedure_Enum  current;

    /**流转目的地 状态： 【zeebe】决定真正的flow Node,这里的状态仅仅是表征含义的。
     * 流程 的下一个节点(不能越级跳转)、 或是回退上一个节点(越级回退能支持？)。
     * 签名签字投票环节的可以简化：状态不会变化，还要等待其他人签字呢，节点环节保留原地踏步。
     * 投票会议的主持人决定 真正的下一个节点流转原则。
     */
    private Procedure_Enum  next;


    /**归属依附通用状态机。 状态机再 去关联 各种各样的业务申请单子或报告。
     * 审批申请单子 or 正在编制的报告,
     * 正在要求流转的和待审批。
     * 一个投票议题，若重新投票(上次投票作废)，apply必须重新生成{没有历史流转签字的数据}。
     * 不是对方 @OneToOne 的哪一个，对方那个实际是单方向关联，本实体不关心它的。
     * 而是对方 @OneToMany 标注的哪一个关系。
     * 【同样】User user也是多对一，可是不会依据user来查询，user也不会删除操作。但是ApprovalStm apply却会删除关联ApprovalStm和过滤查询List<Circulation> his所以必须添加索引！！
     */
    @ManyToOne(fetch= FetchType.LAZY)
    @JoinColumn
    private ApprovalStm apply;

}


/* @数据库修改脚本：
CREATE INDEX circulation_apply_id_index ON public.circulation USING btree (apply_id ASC);
* */